package com.itcoon.cloud.framework.springdoc.plugin;/**
 * @author Athric Yu
 * 2024/11/11
 **/

import com.fasterxml.jackson.databind.type.SimpleType;
import com.itcoon.cloud.framework.enums.BasicEnum;
import com.itcoon.cloud.framework.enums.ValueEnum;
import com.itcoon.cloud.framework.utils.ClassUtil;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.oas.models.media.Schema;
import org.springdoc.core.customizers.PropertyCustomizer;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 *
 *
 * @author Athric Yu
 * 2024/11/11
 **/
public class BasicEnumPropertyCustomizer<V extends Serializable, E extends Enum<E>> implements PropertyCustomizer, BasicEnumCustomizer<V, E> {

    @Override
    public Schema<V> customize(Schema property, AnnotatedType annotatedType) {
        Type type = annotatedType.getType();
        // 检查实例并转换
        if (type instanceof SimpleType) {
            SimpleType fieldType = (SimpleType)type;
            // 获取字段class
            Class<?> fieldClazz = fieldType.getRawClass();
            // 是否是枚举
            if (BasicEnum.class.isAssignableFrom(fieldClazz)) {
                // 获取父接口
                ParameterizedType basicType = (ParameterizedType) ClassUtil.findGenericInterfaceTypeByClass(fieldClazz, BasicEnum.class);
                // 通过父接口获取泛型中枚举值的class类型
                Type actualTypeArgument = basicType.getActualTypeArguments()[0];
                Schema<V> schema = getSchema((Class<V>) actualTypeArgument, property);
                List<V> values = this.getValues((Class<ValueEnum<V, E>>) fieldClazz);
                // 重新设置字段的注释和默认值
                schema.setEnum(values);
                if(!values.isEmpty()){
                    schema.setExample(values.get(0));
                }
                // 获取字段注释
                String description = this.getDescription((Class<BasicEnum<V, E>>) fieldClazz);
                schema.setDescription(property.getDescription() + "=" + description);
                return schema;
            }
        }
        return property;
    }
}
